home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / science / ack3d.zip / ACKINIT.C < prev    next >
Text File  |  1994-01-09  |  10KB  |  369 lines

  1. /******************* ( Animation Construction Kit 3D ) ***********************/
  2. /*             Initialization Routines                 */
  3. /* CopyRight (c) 1993       Author: Lary Myers                     */
  4. /*****************************************************************************/
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <dos.h>
  9. #include <mem.h>
  10. #include <alloc.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <time.h>
  14. #include <string.h>
  15. #include <sys\stat.h>
  16. #include "ack3d.h"
  17. #include "ackeng.h"
  18. #include "ackext.h"
  19. #include "xtypes.h"
  20. #include "xmslib.h"
  21.  
  22. int BuildAckTables(ACKENG *ae);
  23. int ReadAckMapFile(char *fName);
  24. void AckBuildHeightTables(ACKENG *ae);
  25. void BuildAckGrid(ACKENG *ae);
  26.  
  27. /****************************************************************************
  28. ** This **MUST** be the first routine called by the application to setup   **
  29. ** the ACK engine. See the file ACK3D.DOC for what fields need to be       **
  30. ** setup by the application prior to making this call.               **
  31. **                                       **
  32. ****************************************************************************/
  33. int AckInitialize(ACKENG *ae)
  34. {
  35.     int    i,result = 0;
  36.  
  37. if (!ae->WinEndY ||
  38.     !ae->WinEndX ||
  39.     (ae->WinEndY - ae->WinStartY) < 10 ||
  40.     (ae->WinEndX - ae->WinStartX) < 10)
  41.     {
  42.     return(ERR_BADWINDOWSIZE);
  43.     }
  44.  
  45.  
  46. result = BuildAckTables(ae);  /* Read in TRIG.DAT and allocate tables */
  47. if (result)
  48.     return(result);
  49.  
  50. ae->CenterRow       = ae->WinStartY + ((ae->WinEndY - ae->WinStartY) / 2);
  51. ae->WinStartOffset = ae->WinStartY * BYTES_PER_ROW;
  52. ae->WinLength       = ((ae->WinEndY - ae->WinStartY)+1) * DWORDS_PER_ROW;
  53. ae->WinWidth       = (ae->WinEndX - ae->WinStartX) + 1;
  54. ae->WinHeight       = (ae->WinEndY - ae->WinStartY) + 1;
  55.  
  56. AckBuildHeightTables(ae);   /* Build height and adjustment tables */
  57.  
  58. UseXMS = 0;
  59.  
  60. #if USE_XMS
  61.     if (XMSinstalled() != FALSE)
  62.     {
  63.     if (XMSopen(1600) != FALSE)
  64.         UseXMS = 1;
  65.     else
  66.         if (XMSopen(0) != FALSE)
  67.         UseXMS = 1;
  68.  
  69.     if (UseXMS)
  70.         {
  71.         for (i = 0; i < MAX_XARRAY; i++)
  72.         {
  73.         xArray[i].Bmp = (UCHAR far *)malloc(BITMAP_SIZE);
  74.         if (xArray[i].Bmp == NULL)
  75.             {
  76.             XMSclose();
  77.             return(ERR_NOMEMORY);
  78.             }
  79.         xArray[i].count = 0;
  80.         }
  81.         }
  82.     }
  83. #endif
  84.  
  85. return(result);
  86. }
  87.  
  88. /****************************************************************************
  89. ** Internal call to read in the TRIG.DAT file.                   **
  90. **                                       **
  91. ****************************************************************************/
  92. int BuildAckTables(ACKENG *ae)
  93. {
  94.     int    handle,len,ca,na;
  95.     long    fAng;
  96.  
  97. handle = open("trig.dat",O_RDWR|O_BINARY);  /* Does file exist */
  98. if (handle < 1)
  99.     return(ERR_BADFILE);
  100.  
  101. LongTanTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  102. LongInvTanTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  103. CosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  104. SinTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  105. InvSinTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  106. InvCosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  107. LongCosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  108. xNextTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  109. yNextTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
  110. ViewCosTable = (long far *)malloc(sizeof(long) * VIEW_WIDTH);
  111.  
  112. Grid = (unsigned int far *)malloc((GRID_MAX * 2)+1);
  113. ObjGrid = (unsigned int far *)malloc((GRID_MAX * 2)+1);
  114.  
  115. AdjustTable = (long far *)malloc((MAX_DISTANCE+1) * sizeof(long));
  116.  
  117. len = ((ae->WinEndY - ae->WinStartY) + 1) * BYTES_PER_ROW;
  118. ae->BkgdBuffer = (UCHAR far *)malloc(len);
  119. ae->ScreenBuffer = (UCHAR far *)malloc(SCREEN_SIZE);
  120.  
  121. BitmapXferPtr = (UCHAR far *)malloc(BITMAP_SIZE+1);
  122.  
  123. if (LongTanTable == NULL ||
  124.     LongInvTanTable == NULL ||
  125.     CosTable == NULL ||
  126.     SinTable == NULL ||
  127.     InvSinTable == NULL ||
  128.     InvCosTable == NULL ||
  129.     LongCosTable == NULL ||
  130.     xNextTable == NULL ||
  131.     yNextTable == NULL ||
  132.     Grid == NULL ||
  133.     ObjGrid == NULL ||
  134.     AdjustTable == NULL ||
  135.     ae->BkgdBuffer == NULL ||
  136.     ae->ScreenBuffer == NULL ||
  137.     BitmapXferPtr == NULL ||
  138.     ViewCosTable == NULL)
  139.     {
  140.     close(handle);
  141.     return(ERR_NOMEMORY);
  142.     }
  143.  
  144. memset(ae->BkgdBuffer,0,len);
  145. memset(ae->ScreenBuffer,0,SCREEN_SIZE);
  146.  
  147. len = sizeof(long) * INT_ANGLE_360;
  148.  
  149. read(handle,SinTable,len);
  150. read(handle,CosTable,len);
  151. read(handle,LongTanTable,len);
  152. read(handle,LongInvTanTable,len);
  153. read(handle,InvCosTable,len);
  154. read(handle,InvSinTable,len);
  155. read(handle,LongCosTable,len);
  156.  
  157. close(handle);
  158.  
  159. ca = INT_ANGLE_30;
  160. na = -1;
  161.  
  162. for (len = 0; len < VIEW_WIDTH; len++)
  163.     {
  164.     ViewCosTable[len] = LongCosTable[ca];
  165.     ca += na;
  166.     if (ca <= 0)
  167.     {
  168.     ca = -ca;
  169.     na = -na;
  170.     }
  171.     }
  172.  
  173. for (len = 0; len < INT_ANGLE_360; len++)
  174.     {
  175.     yNextTable[len] = (long)GRID_SIZE * LongTanTable[len];
  176.     xNextTable[len] = (long)GRID_SIZE * LongInvTanTable[len];
  177.     }
  178.  
  179. return(0);
  180. }
  181.  
  182. /****************************************************************************
  183. ** This routine is called by the application to read in an ACK map file.   **
  184. ** The map file consist of 4096 integers for the walls followed by 4096       **
  185. ** integers for the objects.                           **
  186. **                                       **
  187. ****************************************************************************/
  188. int AckReadMapFile(ACKENG *ae,char *fName)
  189. {
  190.     int        len,handle,rdlen;
  191.  
  192.  
  193. handle = open(fName,O_RDWR|O_BINARY);
  194. if (handle < 1)
  195.     return(ERR_BADMAPFILE);
  196.  
  197. rdlen = GRID_MAX * 2;
  198.  
  199. len = read(handle,Grid,rdlen);
  200.  
  201. if (len == rdlen)
  202.     len = read(handle,ObjGrid,rdlen);
  203.  
  204. close(handle);
  205.  
  206. if (len != rdlen)
  207.     return(ERR_READINGMAP);
  208.  
  209. BuildAckGrid(ae);        /* Build wall and object XY grids      */
  210.  
  211. return(0);
  212. }
  213.  
  214. /****************************************************************************
  215. ** Internal call used to create the distance tables. Currently the distance**
  216. ** table is only used for the widths of objects.               **
  217. **                                       **
  218. ****************************************************************************/
  219. void AckBuildHeightTables(ACKENG *ae)
  220. {
  221.     int        i,x;
  222.     int        result;
  223.     long    height;
  224.  
  225. height = 18000 - ((ae->WinEndY - ae->WinStartY) * 70);
  226.  
  227. DistanceTable[0] = MAX_HEIGHT;
  228.  
  229. /************** 64 * 65536 ************/
  230. AdjustTable[0] = 4194304L / height;
  231.  
  232. for (i = 1; i < MAX_DISTANCE; i++)
  233.     {
  234.     DistanceTable[i] = height / i;
  235.     if (height - (DistanceTable[i] * i) > (i / 2))
  236.     DistanceTable[i]++;
  237.  
  238.     if (DistanceTable[i] < MIN_HEIGHT)
  239.     DistanceTable[i] = MIN_HEIGHT;
  240.  
  241.     if (DistanceTable[i] > MAX_HEIGHT)
  242.     DistanceTable[i] = MAX_HEIGHT;
  243.  
  244. #if 0
  245.     AdjustTable[i] = 4194304L / DistanceTable[i];
  246. #endif
  247.     AdjustTable[i] = 2097152L / DistanceTable[i];
  248.  
  249.  
  250.     }
  251.  
  252.  
  253. for (i = ae->WinStartX; i < ae->WinEndX; i++)
  254.     Walls[i].LightAdj = 0;
  255.  
  256. }
  257.  
  258. UCHAR    LightArray[] = {255,64,128,192,0,64,128,192,0,64,128,192,0,64,128};
  259.  
  260.  
  261. /****************************************************************************
  262. ** Internal call used to process the map file into the wall and object       **
  263. ** arrays. The application can use the map file for initial placement of   **
  264. ** objects if desired or can setup objects itself once the map file is       **
  265. ** processed.                                   **
  266. **                                       **
  267. ****************************************************************************/
  268. void BuildAckGrid(ACKENG *ae)
  269. {
  270.         int        i,j,CurIndex,pos,x1,y1;
  271.         UINT    MapCode;
  272.  
  273. for (i = 0; i < MAX_DOORS; i++)
  274.     {
  275.     ae->Door[i].ColOffset = 0;
  276.     ae->Door[i].mPos = ae->Door[i].mPos1 = -1;
  277.     }
  278.  
  279. i = (GRID_WIDTH+1) * (GRID_HEIGHT+1);
  280. memset(ae->xGrid,0,i);
  281. memset(ae->yGrid,0,i);
  282.  
  283. CurIndex     = 1;
  284. TotalSpecial = 0;
  285. TotalSecret  = 0;
  286.  
  287. for (i = 0; i < GRID_HEIGHT; i++)
  288.     {
  289.     for (j = 0; j < GRID_WIDTH; j++)
  290.     {
  291.     pos    = (i * GRID_WIDTH) + j;
  292.     MapCode = Grid[pos];
  293.  
  294.     if (MapCode == MAP_STARTCODE)
  295.         {
  296.         ae->yPlayer = pos & 0xFFC0;
  297.         ae->xPlayer = (pos - ae->yPlayer) << 6;
  298.         ae->yPlayer += 32;
  299.         ae->xPlayer += 32;
  300.         continue;
  301.         }
  302.  
  303.     if (MapCode == MAP_UPCODE ||
  304.         MapCode == MAP_DOWNCODE ||
  305.         MapCode == MAP_GOALCODE)
  306.         {
  307.         SpecialCodes[TotalSpecial].mPos = pos;
  308.         SpecialCodes[TotalSpecial++].mCode = MapCode;
  309.         continue;
  310.         }
  311.  
  312.     if (MapCode)            /* Something is in map */
  313.         {
  314.  
  315.         if ((MapCode & 0xFF) != DOOR_YCODE)
  316.         {
  317.         if (ae->xGrid[pos] != DOOR_SIDECODE)
  318.             ae->xGrid[pos] = MapCode;
  319.  
  320.         ae->xGrid[pos+1] = MapCode;
  321.         }
  322.         else
  323.         {
  324.         ae->xGrid[pos]     = DOOR_SIDECODE;
  325.         ae->xGrid[pos+1] = DOOR_SIDECODE;
  326.         }
  327.  
  328.         if ((MapCode & 0xFF) != DOOR_XCODE)
  329.         {
  330.         if (ae->yGrid[pos] != DOOR_SIDECODE)
  331.             ae->yGrid[pos] = MapCode;
  332.         ae->yGrid[pos+GRID_WIDTH] = MapCode;
  333.         }
  334.         else
  335.         {
  336.         ae->yGrid[pos]          = DOOR_SIDECODE;
  337.         ae->yGrid[pos+GRID_WIDTH] = DOOR_SIDECODE;
  338.         }
  339.         }
  340.  
  341.     MapCode = ObjGrid[pos];
  342.     if (MapCode)
  343.         {
  344.         CurIndex = MapCode & 0x7F;
  345.         if (CurIndex < MAX_OBJECTS)
  346.         {
  347.         x1 = (j << 6) + 32;    /* Place object in center of */
  348.         y1 = (i << 6) + 32;    /* the current map square    */
  349.         ae->ObjList[CurIndex].x         = x1;
  350.         ae->ObjList[CurIndex].y         = y1;
  351.         ae->ObjList[CurIndex].mPos   = pos;
  352.         ae->ObjList[CurIndex].VidRow = ae->CenterRow;
  353.         ae->ObjList[CurIndex].Active = 1;
  354.         }
  355.         }
  356.     }
  357.     }
  358.  
  359. j = 0;
  360. for (i = 0; i < GRID_MAX; i++)
  361.     {
  362.     LightMap[i] = LightArray[j];
  363.     }
  364.  
  365. }
  366.  
  367.  
  368.  
  369.